package sbc.corso;

import java.util.Vector;

import sbc.corso.shareable.Platine;
import sbc.corso.shareable.PlatinenFabrikInfo;
import sbc.corso.shareable.Sensor;
import corso.lang.CorsoConnection;
import corso.lang.CorsoDataException;
import corso.lang.CorsoNotification;
import corso.lang.CorsoNotificationItem;
import corso.lang.CorsoReadException;
import corso.lang.CorsoStrategy;
import corso.lang.CorsoTimeoutException;
import corso.lang.CorsoVarOid;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class QualitaetsSicherung {
	
	public QualitaetsSicherung(String workerType, String prid) {
		
		if (workerType.equalsIgnoreCase(CorsoUtil.HELLIGKEITS_PRUEFER))
			System.out.println("Qualitaetspruefung fuer Helligkeit gestartet.");
		if (workerType.equalsIgnoreCase(CorsoUtil.TEMPERATUR_PRUEFER))
			System.out.println("Qualitaetspruefung fuer Temperatur gestartet.");
		if (workerType.equalsIgnoreCase(CorsoUtil.FEUCHTIGKEITS_PRUEFER))
			System.out.println("Qualitaetspruefung fuer Feuchtigkeit gestartet.");
				
		/*
		 * connect to Corso and
		 * get or create PlatinenFabrikInfo
		 */
		CorsoConnection con = CorsoUtil.getCorsoConnection();
		PlatinenFabrikInfo fabrik = CorsoUtil.getPlatinenFabrikInfo(con);
		
		/*
		 * read various Oids
		 */
    	Vector platinenOids = fabrik.getPlatinenOids();
    	Vector sensorenOids = fabrik.getSensorenOids();
    	CorsoVarOid platinenOid = fabrik.getPlatinenOid();
    	CorsoVarOid sensorenOid = fabrik.getSensorenOid();
    	
    	CorsoVarOid newFiredOid;
    	
    	
		//System.out.println ("Starte Notification");

        Vector vect = new Vector ();
	    try	{
	    	/*
	    	 * Add Notifications for Platinen- and SensorenOid
	    	 */
			CorsoNotificationItem platinenNotifItem = new CorsoNotificationItem (
										platinenOid, 
										0, 
										CorsoNotificationItem.CURRENT_TIMESTAMP); 
			vect.add(platinenNotifItem);				
			//System.out.println ("Notification for Platinen " + platinenOid + " added");
			
			CorsoNotificationItem sensorenNotifItem = new CorsoNotificationItem (
									sensorenOid, 
									0, 
									CorsoNotificationItem.CURRENT_TIMESTAMP); 
			vect.add(sensorenNotifItem);				
			//System.out.println ("Notification for Sensoren " + sensorenOid + " added");
			
	    	/*
	    	 * create notifications for all PlatineOids
	    	 */
			for (int i = 0; i < platinenOids.size(); i++) {
	    		CorsoVarOid pOid = (CorsoVarOid)platinenOids.get(i);
				CorsoNotificationItem platineNotifItem = new CorsoNotificationItem (
											pOid, 
											0, 
											CorsoNotificationItem.CURRENT_TIMESTAMP); 
				vect.add(platineNotifItem);				
				//System.out.println ("Notification for Platine " + pOid + " added");
			}
			
	    	/*
	    	 * create notifications for all SensorOids
	    	 */			
			for (int i = 0; i < sensorenOids.size(); i++) {
	    		CorsoVarOid sOid = (CorsoVarOid)sensorenOids.get(i);
		        CorsoNotificationItem sensorNotifItem = new CorsoNotificationItem (
		    								sOid, 
											0, 
											CorsoNotificationItem.CURRENT_TIMESTAMP); 
		        vect.add(sensorNotifItem);
				//System.out.println ("Notification for Sensor " + sOid + " added");
			}	        

	        CorsoNotification notification = con.createNotification(vect, new CorsoStrategy (CorsoUtil.STRATEGY));
		
	        
		    /*
		     * start notification and wait until oid is written
		     */ 
		    for (;;) { 

				//System.out.println ("waiting until oid is written"); 
				CorsoNotificationItem fired = notification.start(CorsoConnection.INFINITE_TIMEOUT, null);
				
				/*
				 * try QS, if possible
				 */
				if (fired != null) { 
					CorsoVarOid firedOid = fired.varOid ();
			    	//System.out.println("firedOid: " + firedOid.toString());
			    	
			    	/*
			    	 * check if firedOid is Platinen- or SensorenOid
			    	 * (this one is fired if a Platine/Sensor was added/removed)
			    	 */
			    	if (firedOid.compareTo(platinenOid) == 0) {
				    	//System.out.println("PlatinenOid fired: " + platinenOid);
				    	// PlatinenOids neu einlesen
				    	platinenOids = fabrik.getPlatinenOids();

				    	/*
				    	 * create notification for new Platine
				    	 */
						for (int i = 0; i < platinenOids.size(); i++) {
				    		CorsoVarOid pOid = (CorsoVarOid)platinenOids.get(i);
							CorsoNotificationItem platineNotifItem = new CorsoNotificationItem (
														pOid, 
														0, 
														CorsoNotificationItem.CURRENT_TIMESTAMP); 
							if (!vect.contains(platineNotifItem))	{
								vect.add(platineNotifItem);	
								//System.out.println("new_platinenoid: " + pOid);
								firedOid = pOid;
							}
							//System.out.println ("Notification for Platine " + pOid + " added");
						}
				    	
			    	}
			    	if (firedOid.compareTo(sensorenOid) == 0) {
				    	//System.out.println("SensorenOid fired: " + sensorenOid);
				    	// SensorenOids neu einlesen
				    	sensorenOids = fabrik.getSensorenOids();
				    	/*
				    	 * create notification for new Sensor
				    	 */
						for (int i = 0; i < sensorenOids.size(); i++) {
				    		CorsoVarOid pOid = (CorsoVarOid)sensorenOids.get(i);
							CorsoNotificationItem sensorNotifItem = new CorsoNotificationItem (
														pOid, 
														0, 
														CorsoNotificationItem.CURRENT_TIMESTAMP); 
							if (!vect.contains(sensorNotifItem))	{
								vect.add(sensorNotifItem);	
								//System.out.println("new_sensorenoid: " + pOid);
								firedOid = pOid;
							}
							//System.out.println ("Notification for Platine " + pOid + " added");
						}
			    	}
			    
			    	
			    	/*
			    	 * get Sensor OR Platine Object from firedOid
			    	 */
			    	Sensor sensor = null;
			    	Platine platine = null;
			    	for (int i = 0; i < platinenOids.size(); i++) {
			    		CorsoVarOid pOid = (CorsoVarOid)platinenOids.get(i);
			    		if ((firedOid.compareTo(pOid) == 0)) {
			    			platine = new Platine(firedOid);
			    		}
			    		else {
			    			//System.out.println("Platine NOT fired: " + pOid);			    			
			    		}			    		
			    	}

			    	for (int i = 0; i < sensorenOids.size(); i++) {
			    		CorsoVarOid sOid = (CorsoVarOid)sensorenOids.get(i);
			    		if (firedOid.compareTo(sOid) == 0) {
			    			//System.out.println("hiiiiiiiiiieeeeeeeeerrrrrrr");
			    			sensor = new Sensor(firedOid);
			    			//System.out.println("Sensor fired: " + sOid);
			    		}
			    		else {
			    			//System.out.println("Sensor NOT fired: " + sOid);			    			
			    		}			    		
			    	}
			    	
			    	
			    	/*
			    	 * check the Sensor depending on the worker type
			    	 */						
	
			    	if (sensor != null) {

						//System.out.println("sensorenOids.size(): " + sensorenOids.size());
						//for (int i = 0; i < sensorenOids.size(); i++) {
					      //  Sensor s = new Sensor((CorsoVarOid)sensorenOids.get(i));
					        Sensor s = sensor;
					        if (workerType.equalsIgnoreCase(CorsoUtil.FEUCHTIGKEITS_PRUEFER))	{
					        	
					        	if (s.getFeuchtigkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_ABER_NOCH_NICHT_GEPRUEFT))	{
					        		s.setFeuchtigkeitsmessung(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT);
					        		Date datumHeute = new Date();
					        		SimpleDateFormat myDateFormat = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
					        		s.setFgeprueftam(myDateFormat.format(datumHeute));
					        		s.setFgeprueftvon(prid);
					        		firedOid.writeShareable (s, CorsoConnection.INFINITE_TIMEOUT);
					        		System.out.println("Fuer Sensor " + s.getId() + " wurde die Qualitaetspruefung fuer Feuchtigkeitsmessung erfolgreich durchgefuehrt.");
					        	}
					        }
					        
					        if (workerType.equalsIgnoreCase(CorsoUtil.HELLIGKEITS_PRUEFER))	{
					        	
					        	if (s.getHelligkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_ABER_NOCH_NICHT_GEPRUEFT))	{
					        		s.setHelligkeitsmessung(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT);
					        		Date datumHeute = new Date();
					        		SimpleDateFormat myDateFormat = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
					        		s.setHgeprueftam(myDateFormat.format(datumHeute));
					        		s.setHgeprueftvon(prid);
					        		firedOid.writeShareable (s, CorsoConnection.INFINITE_TIMEOUT);
					        		System.out.println("Fuer Sensor " + s.getId() + " wurde die Qualitaetspruefung fuer Helligkeitsmessung erfolgreich durchgefuehrt.");
					        	}
					        }
					        
					        if (workerType.equalsIgnoreCase(CorsoUtil.TEMPERATUR_PRUEFER))	{
					        	
					        	if (s.getTemperaturMessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_ABER_NOCH_NICHT_GEPRUEFT))	{	
					        		s.setTemperaturMessung(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT);
					        		Date datumHeute = new Date();
					        		SimpleDateFormat myDateFormat = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
					        		s.setTgeprueftam(myDateFormat.format(datumHeute));
					        		s.setTgeprueftvon(prid);
					        		firedOid.writeShareable (s, CorsoConnection.INFINITE_TIMEOUT);
					        		System.out.println("Fuer Sensor " + s.getId() + " wurde die Qualitaetspruefung fuer Temperaturmessung erfolgreich durchgefuehrt.");
					        	}
					        }

						//}
			    	}

				}
		    }
	    }
		catch (CorsoDataException cde) {
			System.out.println("caught CorsoDataException: " + cde);
		}
		catch (CorsoReadException cre) {
			System.out.println("caught CorsoReadException: " + cre);
		}
		catch (CorsoTimeoutException cte) {
			System.out.println("caught CorsoTimeoutException: " + cte);
		}
		catch (Exception e) {
			System.out.println("caught Exception: " + e);
			e.printStackTrace();
		}
	}	
	
	public static void main(String args[]){
		
		//System.out.println("args[0]" + args[0]);
		//System.out.println("args[1]" + args[1]);
		//System.out.println("args[2]" + args[2]);
		//System.out.println("args[1]" + args[1]);
		new QualitaetsSicherung(args[1],args[2]);
	}	 

}	 

	
	
